`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: Arizona State University
// Engineers: Brentton Garber, Georgii Tkachuk
// 
// Create Date: 17:28:56 04/01/2013 
// Design Name: System
// Module Name: System
// Project Name: Lab 3
// Target Devices: Xilinx Spartan6 XC6LX16-CS324 
// Tool versions: Xilinx ISE 14.2 
// Description: Main module that connects the others together. Contains a button handlers, a fifo,
//					 execution controller, display module and the newly constructed CPU which preforms
//					 Multiplication, addition, and comparison.
//
// Revision: 1
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module system(
	/*global inputs*/
	input wire reset_b,
	input wire go_btn,
	input wire load_btn,
	input wire sys_clk,
	input wire [7:0]byte_in,
	output wire dp_dis,
	output wire full,
	output wire fifo_empty,
	output wire [3:0]dis_control,
	output wire [6:0]seg_data_out);

//Button handlers are active high reset!
wire inv_reset = ~reset_b;

//go_btn_out is the go button input into the execution controller
wire go_btn_out;

but_pulse_gen go_btn_filter(
	.btn_out(go_btn_out), 
	.btn_in(go_btn), 
	.sys_clk(sys_clk), 
	.reset(reset_b));

wire filtered_load;
// Load button is filtered by a button handler.
// It outputs single clock-wide pulse
but_pulse_gen load_btn_filter(
	.btn_out(filtered_load), 
	.btn_in(load_btn), 
	.sys_clk(sys_clk), 
	.reset(reset_b));

// instance of execution controller takes in the filtered 
// go button as well as the full input from the fifo.
wire control_o_pop;
wire empty;

exec_ctrl #(.N(100)) controller(
	.i_go(go_btn_out), 
	.i_stop(empty),
	.sys_clk(sys_clk), 
	.pop_data(control_o_pop));

//switch filter is active low reset
//filtered_byte is the input into the fifo
wire [7:0]filtered_byte;
switch_latcher_8_bit switch_filter(
	.i_switch_bus(byte_in), 
	.reset(~reset_b), 
	.sys_clk(sys_clk), 
	.o_switch_reg(filtered_byte));

wire slow_clk;
// Initialize the clock divider
clock_divider clk_div(
	.reset(inv_reset), 
	.full_clk(sys_clk), 
	.half_clk(slow_clk));

assign full = fifo_full;
assign empty = fifo_empty;

wire [7:0]fifo_o_byte;

// initialize the fifo module
async_fifo #(.SIZE(12)) this_fifo(
	.i_byte(filtered_byte),
	.wclk(sys_clk),
	.rclk(slow_clk),
	.i_push(filtered_load),
	.i_pop(control_o_pop),
	.reset_b(inv_reset),
	.o_empty(fifo_empty),
	.o_full(fifo_full),
	.o_byte(fifo_o_byte));
	
wire [3:0]dis_data;
wire [1:0]dis_addr;

// Initialize the CPU module and connect it to proper components
CPU cpu(
	.instr_data(fifo_o_byte),
	.instr_exec(control_o_pop),
	.clk(slow_clk),
	.reset(inv_reset),
	.reg_data(dis_data),
	.dis_addr(dis_addr));
	
// Initialize the segment display
seg_display display(
	.sys_clk(sys_clk),
	.reset_b(inv_reset),    
	.reg_data(dis_data), 	  // 8bit input
	.reg_addr(dis_addr),
	// 7-Segment LED Display Interface // -----------------------------------
	.dp_dis(dp_dis),        // Period Display
	.dis_control(dis_control),   // Select which of the 4x7-Segment LED 
									 // Displays to activate.
	.led_dis(seg_data_out));  

endmodule



